/*
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package vn.student.util;

import static vn.student.util.CommonUtilities.SERVER_URL;
import static vn.student.util.CommonUtilities.TAG;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;

import android.R.integer;
import android.content.Context;
import android.util.Log;

import com.google.android.gcm.GCMRegistrar;


/**
 * Helper class used to communicate with the demo server.
 */
public final class ServerUtilities {

    private static final int MAX_ATTEMPTS = 5;
    private static final int BACKOFF_MILLI_SECONDS = 2000;
    private static final Random random = new Random();

    /**
     * Register this account/device pair within the server.
     * 
     * @return whether the registration succeeded or not.
     */
    static final String TAG2="Luc test";
    public static boolean register(final Context context, Map<String,String> params) {

	String serverUrl = SERVER_URL + "/register";
	//Log.d(tag, msg)
	long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
	
	for (int i = 1; i <= MAX_ATTEMPTS; i++) {
	    Log.d(TAG, "Attempt #" + i + " to register");
	    try {
		
		Log.d(TAG2, serverUrl);		
		
		post(serverUrl, params);
		GCMRegistrar.setRegisteredOnServer(context, true);
		//String message = context.getString(R.string.server_registered);
		//Log.d("OK", message);

		return true;
	    } catch (IOException e) {		
		Log.e(TAG, "Failed to register on attempt " + i, e);
		if (i == MAX_ATTEMPTS) {
		    break;
		}
		try {
		    Log.d(TAG, "Sleeping for " + backoff + " ms before retry");
		    Thread.sleep(backoff);
		} catch (InterruptedException e1) {
		    // Activity finished before we complete - exit.
		    Log.d(TAG, "Thread interrupted: abort remaining retries!");
		    Thread.currentThread().interrupt();
		    return false;
		}
		// increase backoff exponentially
		//backoff *= 2;
	    }
	}
//	String message = context.getString(R.string.server_register_error,MAX_ATTEMPTS);
	
	return false;
    }

    /**
     * Unregister this account/device pair within the server.
     */
    public static void unregister(final Context context, final String regId) {
	Log.i(TAG, "unregistering device (regId = " + regId + ")");
	String serverUrl = SERVER_URL + "/unregister";
	Map<String, String> params = new HashMap<String, String>();
	params.put("redID", regId);
	try {
	    post(serverUrl, params);
	    GCMRegistrar.setRegisteredOnServer(context, true);
	   // String message = context.getString(R.string.server_unregistered);

	} catch (IOException e) {	 
//	    String message = context.getString(R.string.server_unregister_error, e.getMessage());

	}
    }

    /**
     * Issue a POST request to the server.
     * 
     * @param endpoint
     *            POST address.
     * @param params
     *            request parameters.
     * 
     * @throws IOException
     *             propagated from POST.
     */
    private static void post(String endpoint, Map<String, String> params)
	    throws IOException {
	URL url;
	try {
	    url = new URL(endpoint);
	} catch (MalformedURLException e) {
	    throw new IllegalArgumentException("invalid url: " + endpoint);
	}
	StringBuilder bodyBuilder = new StringBuilder();
	Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
	// constructs the POST body using the parameters
	while (iterator.hasNext()) {
	    Entry<String, String> param = iterator.next();
	    bodyBuilder.append(param.getKey()).append('=')
		    .append(param.getValue());
	    if (iterator.hasNext()) {
		bodyBuilder.append('&');
	    }
	}
	String body = bodyBuilder.toString();
	Log.v(TAG, "Posting '" + body + "' to " + url);
	byte[] bytes = body.getBytes();
	HttpURLConnection conn = null;
	try {
	    conn = (HttpURLConnection) url.openConnection();
	    conn.setDoOutput(true);
	    conn.setUseCaches(false);
	    conn.setFixedLengthStreamingMode(bytes.length);
	    conn.setRequestMethod("POST");
	    conn.setRequestProperty("Content-Type",
		    "application/x-www-form-urlencoded;charset=UTF-8");
	    // post the request
	    OutputStream out = conn.getOutputStream();
	    out.write(bytes);
	    out.close();

	    // handle the response
	    int status = conn.getResponseCode();
	    if (status != 200) {
		throw new IOException("Post failed with error code " + status);
	    }
	} 	
	finally {
	    if (conn != null) {
		conn.disconnect();
	    }
	}
    }
}
